//为完成教材练习题而写的类，已通过教材给出的测试样例，但没有考虑一些特殊情况
public class Triangle2D {
    private Point a;
    private Point b;
    private Point c;

    public Point getA() {
        return a;
    }

    public Point getB() {
        return b;
    }

    public Point getC() {
        return c;
    }

    public void setA(double x, double y) {
        a.x = x;
        a.y = y;
    }

    public void setB(double x, double y) {
        b.x = x;
        b.y = y;
    }

    public void setC(double x, double y) {
        c.x = x;
        c.y = y;
    }

    public Triangle2D() {
        a = new Point();
        b = new Point(1, 1);
        c = new Point(2, 5);
    }

    public Triangle2D(double ax, double ay, double bx, double by, double cx, double cy) {
        a = new Point(ax, ay);
        b = new Point(bx, by);
        c = new Point(cx, cy);
    }

    public Triangle2D(Point a, Point b, Point c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public double getArea() {
        double p = getPerimeter() / 2;
        return Math.sqrt(p * (p - a.distance(b)) * (p - a.distance(c)) * (p - b.distance(c)));
    }

    public double getPerimeter() {
        double ab = a.distance(b);
        double ac = a.distance(c);
        double bc = b.distance(c);
        return ab + ac + bc;
    }

    //判断点是否在三角形内
    //包含点在边上或者与顶点重合的情况
    public boolean doesContain(Point p) {
        if (!Geometry.doesSegmentIntersectInternally(a, p, b, c)
                && !Geometry.doesSegmentIntersectInternally(b, p, a, c)
                && !Geometry.doesSegmentIntersectInternally(c, p, a, b)) return true;
        else if (p.equals(a) || p.equals(b) || p.equals(c)) return true;
        else return false;
    }

    //判断另一个三角形是否在此三角形内
    public boolean doesContain(Triangle2D t) {
        if (doesContain(t.a) && doesContain(t.b) && doesContain(t.c)) return true;
        else return false;
    }

    //判断另一个三角形是否与此三角形重叠
    //包含另一个三角形被包含在此三角形内的情况
    public boolean doesOverlap(Triangle2D t) {
        if (doesContain(t)) return true;
        //依次判断此三角形与传入三角形的各边是否满足线段内相交
        if (Geometry.doesSegmentIntersectInternally(a, b, t.a, t.b)) return true;
        else if (Geometry.doesSegmentIntersectInternally(a, b, t.a, t.c)) return true;
        else if (Geometry.doesSegmentIntersectInternally(a, b, t.b, t.c)) return true;
        else if (Geometry.doesSegmentIntersectInternally(a, c, t.a, t.b)) return true;
        else if (Geometry.doesSegmentIntersectInternally(a, c, t.a, t.c)) return true;
        else if (Geometry.doesSegmentIntersectInternally(a, c, t.b, t.c)) return true;
        else if (Geometry.doesSegmentIntersectInternally(b, c, t.a, t.b)) return true;
        else if (Geometry.doesSegmentIntersectInternally(b, c, t.a, t.c)) return true;
        else if (Geometry.doesSegmentIntersectInternally(b, c, t.b, t.c)) return true;
        return false;
    }

    public void printArea() {
        double area = Math.round(getArea() * 100) * 1.0 / 100;
        System.out.println("Area: " + area);
    }

    public void printPerimeter() {
        double p = Math.round(getPerimeter() * 100) * 1.0 / 100;
        System.out.println("Perimeter: " + p);
    }

    public static void main(String args[]) {
        Triangle2D t1 = new Triangle2D(new Point(2.5, 2), new Point(4.2, 3), new Point(5, 3.5));
        t1.printPerimeter();
        t1.printArea();
        System.out.println(t1.doesContain(new Point(3, 3)));
        System.out.println(t1.doesContain(new Triangle2D(new Point(2.9, 2), new Point(4, 1), new Point(1, 3.4))));
        System.out.println(t1.doesOverlap(new Triangle2D(new Point(2, 5.5), new Point(4, -3), new Point(2, 6.5))));
    }
}

class Point {
    double x;
    double y;

    public Point() {
        this(0, 0);
    }

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double distance(Point p) {
        return distance(p.x, p.y);
    }

    public double distance(double x, double y) {
        return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2));
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public boolean equals(Point p) {
        final double eps = 1e-6;
        if (Math.abs(x - p.x) < eps && Math.abs(y - p.y) < eps) return true;
        else return false;
    }
}